package com.huawei.codearts.config;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * TTL+死信队列 组合实现延迟队列
 */
@Configuration
public class DelayMQConfig {

    /**
     * 声明队列
     */
    public static final String ORDER_QUEUE_NAME = "order_queue";
    /**
     * 声明死信队列
     */
    public static final String ORDER_QUEUE_DLX_NAME = "order_queue_dlx";
    /**
     * 声明交换机
     */
    public static final String ORDER_EXCHANGE_NAME = "order_exchange";
    /**
     * 声明死信交换机
     */
    public static final String ORDER_EXCHANGE_DLX_NAME = "order_exchange_dlx";

    /**
     * 声明routing key
     */
    public static final String ROUTING_KEY = "order.#";
    /**
     * 声明死信队列routing key
     */
    public static final String DLX_ROUTING_KEY = "dlx.order.#";

    /**
     * 创建普通队列,在创建普通队列的时候，需要与死信队列进行绑定
     */
    @Bean(name = "orderQueue")
    public Queue testDlxQueue() {
        /*
         * 在创建普通队列的时候，需要同时绑定死信交换机
         * 需要两个参数：
         *   1、 x-dead-letter-exchange  死信交换机名称
         *   2、 x-dead-letter-routing-key  发送给死信交换机的routingKey  必须匹配上死信队列的routingKey
         */
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", ORDER_EXCHANGE_DLX_NAME);
        arguments.put("x-dead-letter-routing-key", "dlx.order.cancel");
        //设置队列过期时间 毫秒 可根据实际需求修改过期时间 例如：30分钟后取消未支付订单 ttl=1000*60*30
        arguments.put("x-message-ttl", 10000);
        //设置队列的长度限制  超出长度限制时，根据队列的先进先出的特性，最先发送的消息会先进入死信队列
//        arguments.put("x-max-length", 10);
        // 设置优先级 官方允许设置的优先级范围是 0 ~ 255 之间，此处设置为 10 即允许优先级范围是 0 ~ 10，不要设置过大，浪费内存
        // .maxPriority(10)
        return QueueBuilder.durable(ORDER_QUEUE_NAME).withArguments(arguments).build();
    }

    /**
     * 创建普通交换机
     */
    @Bean(name = "orderExchange")
    public Exchange testDlxExchange() {
        return ExchangeBuilder.topicExchange(ORDER_EXCHANGE_NAME).durable(true).build();
    }


    /**
     * 绑定普通交换机和队列
     */
    @Bean
    public Binding testDlxBinding(@Qualifier("orderQueue") Queue queue,
                                  @Qualifier("orderExchange") Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(ROUTING_KEY).noargs();
    }

    /**
     * 创建死信队列
     */
    @Bean(name = "dlxOrderQueue")
    public Queue dlxQueue() {
        return QueueBuilder.durable(ORDER_QUEUE_DLX_NAME).build();
    }

    /**
     * 创建死信交换机
     */
    @Bean(name = "dlxOrderExchange")
    public Exchange dlxExchange() {
        return ExchangeBuilder.topicExchange(ORDER_EXCHANGE_DLX_NAME).durable(true).build();
    }


    /**
     * 绑定死信交换机和队列
     */
    @Bean
    public Binding dlxBinding(@Qualifier("dlxOrderQueue") Queue queue,
                              @Qualifier("dlxOrderExchange") Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(DLX_ROUTING_KEY).noargs();
    }

}